﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.SceneManagement;
using Random = System.Random;

namespace ScFramework.Core
{
    /// <summary>
    /// 程序入口，对各项管理类进行初始化操作。
    /// </summary>
    public class Main : MonoBehaviour
    {
        public static float ObejectBlockSize = 8;

        /// <summary>
        /// 入口流程。
        /// </summary>
        public string StartProcedure;


        private static Main _instance;

        private static Random rand = null;
        private bool isLoadingScene = false;
        bool onCoroutine = false;


        public int TempUserID = 1;

        /// <summary>
        /// 系统组件列表
        /// </summary>
        private List<ISystemModule> _modules;


        /// <summary>
        /// 获取系统组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Get<T>() where T : ISystemModule
        {
            foreach (var x in _modules)
            {
                if (x is T)
                {
                    return (T) x;
                }
            }

            Debug.LogError($"{_instance}:未找到组件" + typeof(T).ToString());
            return default(T);
        }


        /// <summary>
        ///  初始化各项全局管理。
        /// </summary>
        private void Awake()
        {
            FullScreenMode mode = FullScreenMode.FullScreenWindow;
            if (Screen.width * 9f < Screen.height * 16)
            {
                Screen.SetResolution(Screen.width, (int) (Screen.width * (9.0000f / 16.0000f)), mode);
            }
            else
            {
                Screen.SetResolution((int) (Screen.height * (16.0000f / 9.0000f)), Screen.height, mode);
            }

            if (_instance != null)
            {
                Debug.LogError($"{this}:存在多个实例");
            }

            _instance = this;

            _modules = new List<ISystemModule>();

            _modules.Add(new ResourceManager());
            _modules.Add(new TypeManager());
            _modules.Add(new MessageManager());
            _modules.Add(new ProcedureManager());
            _modules.Add(new DataUtil());
            _modules.Add(new UserManager());
            _modules.Add(new UIManager());
            _modules.Add(new InputManager());


            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].Initialize(this);
                if (_modules[i] is INeedRemove a)
                {
                    needRemoveList.Add(a);
                }
            }

            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].Enable();
            }


#if GUI
            Get<UIManager>().Open("3rdPart/DebugCommandUI", 5);
#endif
        }

        List<INeedRemove> needRemoveList = new List<INeedRemove>();

        public void DoRemove(object obj)
        {
            foreach (var x in needRemoveList)
            {
                x.RemoveAbout(obj);
            }
        }

        /// <summary>
        ///  开始流程。
        /// </summary>
        private void Start()
        {
            Get<ProcedureManager>().ChangeTo(StartProcedure);
        }

        /// <summary>
        /// Unity每帧更新。
        /// </summary>
        private void Update()
        {
            deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f;
            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].SysUpdate(Time.deltaTime);
            }
        }


        /// <summary>
        /// Unity每帧更新。
        /// </summary>
        private void LateUpdate()
        {
            deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f;
            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].SysLateUpdate(Time.deltaTime);
            }
        }

        /// <summary>
        /// Unity每帧更新。
        /// </summary>
        private void FixedUpdate()
        {
            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].SysFixedUpdate(Time.fixedDeltaTime);
            }

            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].SysLateFixedUpdate();
            }
        }

        /// <summary>
        /// 当退出时调用。
        /// </summary>
        private void OnDestroy()
        {
            for (int i = 0; i < _modules.Count; i++)
            {
                _modules[i].Dispose();
            }
        }

        float deltaTime = 0.0f;


        void OnGUI()
        {
            int w = Screen.width, h = Screen.height;

            GUIStyle style = new GUIStyle();

            Rect rect = new Rect(0, 0, w, h * 2 / 100);
            style.alignment = TextAnchor.UpperLeft;
            style.fontSize = h * 2 / 100;
            //new Color (0.0f, 0.0f, 0.5f, 1.0f);
            style.normal.textColor = Color.white;
            float msec = deltaTime * 1000.0f;
            float fps = 1.0f / deltaTime;
            string text = string.Format("{0:0.0} ms ({1:0.} fps)", msec, fps);
            GUI.Label(rect, text, style);
        }
    }

    public interface INeedRemove
    {
        void RemoveAbout(object obj);
    }
}


public class ObjectArgs<T> : EventArgs
{
    public T obj;

    public ObjectArgs(T x)
    {
        obj = x;
    }
}